home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / cfb / cfbfillsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-15  |  21.3 KB  |  764 lines

  1. /************************************************************
  2. Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
  3.  
  4.                     All Rights Reserved
  5.  
  6. Permission  to  use,  copy,  modify,  and  distribute   this
  7. software  and  its documentation for any purpose and without
  8. fee is hereby granted, provided that the above copyright no-
  9. tice  appear  in all copies and that both that copyright no-
  10. tice and this permission notice appear in  supporting  docu-
  11. mentation,  and  that the names of Sun or MIT not be used in
  12. advertising or publicity pertaining to distribution  of  the
  13. software  without specific prior written permission. Sun and
  14. M.I.T. make no representations about the suitability of this
  15. software for any purpose. It is provided "as is" without any
  16. express or implied warranty.
  17.  
  18. SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
  19. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
  20. NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
  21. ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
  23. PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
  24. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  25. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  
  27. ********************************************************/
  28.  
  29. /***********************************************************
  30. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  31. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  32.  
  33.                         All Rights Reserved
  34.  
  35. Permission to use, copy, modify, and distribute this software and its 
  36. documentation for any purpose and without fee is hereby granted, 
  37. provided that the above copyright notice appear in all copies and that
  38. both that copyright notice and this permission notice appear in 
  39. supporting documentation, and that the names of Digital or MIT not be
  40. used in advertising or publicity pertaining to distribution of the
  41. software without specific, written prior permission.  
  42.  
  43. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  44. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  45. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  46. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  47. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  48. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  49. SOFTWARE.
  50.  
  51. ******************************************************************/
  52.  
  53. /* $XConsortium: cfbfillsp.c,v 5.7 89/11/24 18:09:00 rws Exp $ */
  54.  
  55. #include "X.h"
  56. #include "Xmd.h"
  57. #include "servermd.h"
  58. #include "gcstruct.h"
  59. #include "window.h"
  60. #include "pixmapstr.h"
  61. #include "scrnintstr.h"
  62. #include "windowstr.h"
  63.  
  64. #include "cfb.h"
  65. #include "cfbmskbits.h"
  66.  
  67. extern void mfbInvertSolidFS(), mfbBlackSolidFS(), mfbWhiteSolidFS();
  68.  
  69. /* scanline filling for color frame buffer
  70.    written by drewry, oct 1986 modified by smarks
  71.    changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
  72.  
  73.    these routines all clip.  they assume that anything that has called
  74. them has already translated the points (i.e. pGC->miTranslate is
  75. non-zero, which is howit gets set in cfbCreateGC().)
  76.  
  77.    the number of new scnalines created by clipping ==
  78. MaxRectsPerBand * nSpans.
  79.  
  80.     FillSolid is overloaded to be used for OpaqueStipple as well,
  81. if fgPixel == bgPixel.  
  82. Note that for solids, PrivGC.rop == PrivGC.ropOpStip
  83.  
  84.  
  85.     FillTiled is overloaded to be used for OpaqueStipple, if
  86. fgPixel != bgPixel.  based on the fill style, it uses
  87. {RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
  88. */
  89.  
  90. #ifdef    notdef
  91. #include    <stdio.h>
  92. static
  93. dumpspans(n, ppt, pwidth)
  94.     int    n;
  95.     DDXPointPtr ppt;
  96.     int *pwidth;
  97. {
  98.     fprintf(stderr,"%d spans\n", n);
  99.     while (n--) {
  100.     fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
  101.     ppt++;
  102.     pwidth++;
  103.     }
  104.     fprintf(stderr, "\n");
  105. }
  106. #endif
  107.  
  108. void
  109. cfbSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  110.     DrawablePtr pDrawable;
  111.     GCPtr    pGC;
  112.     int        nInit;            /* number of spans to fill */
  113.     DDXPointPtr pptInit;        /* pointer to list of start points */
  114.     int        *pwidthInit;        /* pointer to list of n widths */
  115.     int     fSorted;
  116. {
  117.                 /* next three parameters are post-clip */
  118.     int n;            /* number of spans to fill */
  119.     DDXPointPtr ppt;        /* pointer to list of start points */
  120.     int *pwidth;        /* pointer to list of n widths */
  121.     int *addrlBase;        /* pointer to start of bitmap */
  122.     int nlwidth;        /* width in longwords of bitmap */
  123.     register int *addrl;    /* pointer to current longword in bitmap */
  124.     register int width;        /* current span width */
  125.     register int nlmiddle;
  126.     register int fill;
  127.     register int x;
  128.     register int startmask;
  129.     register int endmask;
  130.     int rop;            /* rasterop */
  131.     int planemask;
  132.     int *pwidthFree;        /* copies of the pointers to free */
  133.     DDXPointPtr pptFree;
  134.  
  135.     if (!(planemask = pGC->planemask))
  136.     return;
  137.  
  138.     n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip);
  139.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  140.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  141.     if(!pptFree || !pwidthFree)
  142.     {
  143.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  144.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  145.     return;
  146.     }
  147. #ifdef    notdef
  148.     dumpspans(n, pptInit, pwidthInit);
  149. #endif
  150.     pwidth = pwidthFree;
  151.     ppt = pptFree;
  152.     n = miClipSpans(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip,
  153.              pptInit, pwidthInit, nInit,
  154.              ppt, pwidth, fSorted);
  155.  
  156. #ifdef    notdef
  157.     dumpspans(n, ppt, pwidth);
  158. #endif
  159.     if (pDrawable->type == DRAWABLE_WINDOW)
  160.     {
  161.     addrlBase = (int *)
  162.         (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate.ptr);
  163.     nlwidth = (int)
  164.           (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
  165.     }
  166.     else
  167.     {
  168.     addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate.ptr);
  169.     nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
  170.     }
  171.  
  172.     rop = pGC->alu;
  173.     fill = PFILL(pGC->fgPixel);
  174.     planemask = PFILL(planemask);
  175.  
  176.     if (rop == GXcopy && (planemask & PMSK) == PMSK)
  177.     {
  178.     while (n--)
  179.     {
  180.         x = ppt->x;
  181.         addrl = addrlBase + (ppt->y * nlwidth);
  182.         ++ppt;
  183.         width = *pwidth++;
  184.         if (!width)
  185.         continue;
  186. #if PPW == 4
  187.         if (width <= 4)
  188.         {
  189.         register char    *addrb;
  190.  
  191.         addrb = ((char *) addrl) + x;
  192.         while (width--)
  193.             *addrb++ = fill;
  194.         }
  195. #else
  196.         if ( ((x & PIM) + width) <= PPW)
  197.         {
  198.         addrl += x >> PWSH;
  199.         maskpartialbits(x, width, startmask);
  200.         *addrl = (*addrl & ~startmask) | (fill & startmask);
  201.         }
  202. #endif
  203.         else
  204.         {
  205.         addrl += x >> PWSH;
  206.         maskbits(x, width, startmask, endmask, nlmiddle);
  207.         if ( startmask ) {
  208.             *addrl = *addrl & ~startmask | fill & startmask;
  209.             ++addrl;
  210.         }
  211.         while ( nlmiddle-- )
  212.             *addrl++ = fill;
  213.         if ( endmask )
  214.             *addrl = *addrl & ~endmask | fill & endmask;
  215.         }
  216.     }
  217.     }
  218.     else if ((rop == GXxor && (planemask & PMSK) == PMSK) || rop == GXinvert)
  219.     {
  220.     if (rop == GXinvert)
  221.         fill = planemask;
  222.     while (n--)
  223.     {
  224.         x = ppt->x;
  225.         addrl = addrlBase + (ppt->y * nlwidth);
  226.         ++ppt;
  227.         width = *pwidth++;
  228.         if (!width)
  229.         continue;
  230. #if PPW == 4
  231.         if (width <= 4)
  232.         {
  233.         register char    *addrb;
  234.  
  235.         addrb = ((char *) addrl) + x;
  236.         while (width--)
  237.             *addrb++ ^= fill;
  238.         }
  239. #else
  240.         if ( ((x & PIM) + width) <= PPW)
  241.         {
  242.         addrl += x >> PWSH;
  243.         maskpartialbits(x, width, startmask);
  244.         *addrl ^= (fill & startmask);
  245.         }
  246. #endif
  247.         else
  248.         {
  249.         addrl += x >> PWSH;
  250.         maskbits(x, width, startmask, endmask, nlmiddle);
  251.         if ( startmask )
  252.             *addrl++ ^= (fill & startmask);
  253.         while ( nlmiddle-- )
  254.             *addrl++ ^= fill;
  255.         if ( endmask )
  256.             *addrl ^= (fill & endmask);
  257.         }
  258.     }
  259.     }
  260.     else
  261.     {
  262.         while (n--)
  263.         {
  264.         x = ppt->x;
  265.         addrl = addrlBase + (ppt->y * nlwidth) + (x >> PWSH);
  266.         ++ppt;
  267.         width = *pwidth++;
  268.         if (width)
  269.         {
  270.             if ( ((x & PIM) + width) <= PPW)
  271.             {
  272.             maskpartialbits(x, width, startmask);
  273.             *addrl = *addrl & ~(planemask & startmask) |
  274.                  DoRop(rop, fill, *addrl) & (planemask & startmask);
  275.             }
  276.             else
  277.             {
  278.             maskbits(x, width, startmask, endmask, nlmiddle);
  279.             if ( startmask ) {
  280.             *addrl = *addrl & ~(planemask & startmask) |
  281.                      DoRop (rop, fill, *addrl) & (planemask & startmask);
  282.                 ++addrl;
  283.             }
  284.             while ( nlmiddle-- ) {
  285.             *addrl = (*addrl & ~planemask) |
  286.                  DoRop (rop, fill, *addrl) & planemask;
  287.                 ++addrl;
  288.             }
  289.             if ( endmask ) {
  290.             *addrl = *addrl & ~(planemask & endmask) |
  291.                      DoRop (rop, fill, *addrl) & (planemask & endmask);
  292.             }
  293.             }
  294.         }
  295.         }
  296.     }
  297.     DEALLOCATE_LOCAL(pptFree);
  298.     DEALLOCATE_LOCAL(pwidthFree);
  299. }
  300.  
  301.  
  302. /* Fill spans with tiles that aren't 32 bits wide */
  303. void
  304. cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  305. DrawablePtr pDrawable;
  306. GC        *pGC;
  307. int        nInit;        /* number of spans to fill */
  308. DDXPointPtr pptInit;        /* pointer to list of start points */
  309. int *pwidthInit;        /* pointer to list of n widths */
  310. int fSorted;
  311. {
  312.     int        iline;        /* first line of tile to use */
  313.                 /* next three parameters are post-clip */
  314.     int n;            /* number of spans to fill */
  315.     register DDXPointPtr ppt;    /* pointer to list of start points */
  316.     register int *pwidth;    /* pointer to list of n widths */
  317.     int        *addrlBase;    /* pointer to start of bitmap */
  318.     int         nlwidth;    /* width in longwords of bitmap */
  319.     register int *pdst;        /* pointer to current word in bitmap */
  320.     register int *psrc;        /* pointer to current word in tile */
  321.     register int nlMiddle;
  322.     register int startmask;
  323.     PixmapPtr    pTile;        /* pointer to tile we want to fill with */
  324.     int        w, width, x, tmpSrc, srcStartOver, nstart, nend;
  325.     int        xSrc, ySrc;
  326.     int     endmask, tlwidth, rem, tileWidth, *psrcT, rop;
  327.     int        tileHeight;
  328.     int *pwidthFree;        /* copies of the pointers to free */
  329.     DDXPointPtr pptFree;
  330.  
  331.     if (!(pGC->planemask))
  332.     return;
  333.  
  334.     n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip);
  335.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  336.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  337.     if(!pptFree || !pwidthFree)
  338.     {
  339.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  340.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  341.     return;
  342.     }
  343.     pwidth = pwidthFree;
  344.     ppt = pptFree;
  345.     n = miClipSpans(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip,
  346.              pptInit, pwidthInit, nInit, 
  347.              ppt, pwidth, fSorted);
  348.  
  349.     if (pGC->fillStyle == FillTiled)
  350.     {
  351.     pTile = pGC->tile.pixmap;
  352.     tlwidth = pTile->devKind >> 2;
  353.     rop = pGC->alu;
  354.     }
  355.     else
  356.     {
  357.     pTile = pGC->stipple;
  358.     tlwidth = pTile->devKind >> 2;
  359.     rop = pGC->alu;
  360.     }
  361.  
  362.     xSrc = pDrawable->x;
  363.     ySrc = pDrawable->y;
  364.  
  365.     if (pDrawable->type == DRAWABLE_WINDOW)
  366.     {
  367.     addrlBase = (int *)
  368.         (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate.ptr);
  369.     nlwidth = (int)
  370.           (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
  371.     }
  372.     else
  373.     {
  374.     addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate.ptr);
  375.     nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
  376.     }
  377.  
  378.     tileWidth = pTile->drawable.width;
  379.     tileHeight = pTile->drawable.height;
  380.  
  381.     /* this replaces rotating the tile. Instead we just adjust the offset
  382.      * at which we start grabbing bits from the tile.
  383.      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
  384.      * so that iline and xrem always stay within the tile bounds.
  385.      */
  386.     xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
  387.     ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
  388.  
  389.     while (n--)
  390.     {
  391.     iline = (ppt->y - ySrc) % tileHeight;
  392.         pdst = addrlBase + (ppt->y * nlwidth) + (ppt->x >> PWSH);
  393.         psrcT = (int *) pTile->devPrivate.ptr + (iline * tlwidth);
  394.     x = ppt->x;
  395.  
  396.     if (*pwidth)
  397.     {
  398.         width = *pwidth;
  399.         while(width > 0)
  400.         {
  401.         rem = (x - xSrc) % tileWidth;
  402.         psrc = psrcT + rem / PPW;
  403.             w = min(tileWidth, width);
  404.         w = min(w,tileWidth-rem);
  405. #ifdef notdef
  406.         if((rem = x % tileWidth) != 0)
  407.         {
  408.             w = min(min(tileWidth - rem, width), PPW);
  409.             /* we want to grab from the end of the tile.  Figure
  410.              * out where that is.  In general, the start of the last
  411.              * word of data on this scanline is tlwidth -1 words 
  412.              * away. But if we want to grab more bits than we'll
  413.              * find on that line, we have to back up 1 word further.
  414.              * On the other hand, if the whole tile fits in 1 word,
  415.              * let's skip the work */ 
  416.             endinc = tlwidth - 1 - (tileWidth-rem) / PPW;
  417.  
  418.             if(endinc)
  419.             {
  420.             if((rem & PIM) + w > tileWidth % PPW)
  421.                 endinc--;
  422.             }
  423.  
  424.             getbits(psrc + endinc, rem & PIM, w, tmpSrc);
  425.             putbitsrop(tmpSrc, (x & PIM), w, pdst, 
  426.             pGC->planemask, rop);
  427.             if((x & PIM) + w >= PPW)
  428.             pdst++;
  429.         }
  430.         else
  431. #endif /* notdef */
  432.         if(((x & PIM) + w) <= PPW)
  433.         {
  434.             getbits(psrc, (rem & PIM), w, tmpSrc);
  435.             putbitsrop(tmpSrc, x & PIM, w, pdst, 
  436.             pGC->planemask, rop);
  437.             if ((x & PIM) + w == PPW) ++pdst;
  438.         }
  439.         else
  440.         {
  441.             maskbits(x, w, startmask, endmask, nlMiddle);
  442.  
  443.                 if (startmask)
  444.                 nstart = PPW - (x & PIM);
  445.                 else
  446.                 nstart = 0;
  447.                 if (endmask)
  448.                     nend = (x + w)  & PIM;
  449.                 else
  450.                 nend = 0;
  451.  
  452.                 srcStartOver = nstart + (rem & PIM) > PLST;
  453.  
  454.             if(startmask)
  455.             {
  456.             getbits(psrc, rem & PIM, nstart, tmpSrc);
  457.             putbitsrop(tmpSrc, x & PIM, nstart, pdst, 
  458.                 pGC->planemask, rop);
  459.             pdst++;
  460.             if(srcStartOver)
  461.                 psrc++;
  462.             }
  463.             nstart = (nstart + rem) & PIM;
  464.             while(nlMiddle--)
  465.             {
  466.                 getbits(psrc, nstart, PPW, tmpSrc);
  467.                 putbitsrop( tmpSrc, 0, PPW,
  468.                 pdst, pGC->planemask, rop );
  469.                 pdst++;
  470.                 psrc++;
  471.             }
  472.             if(endmask)
  473.             {
  474.             getbits(psrc, nstart, nend, tmpSrc);
  475.             putbitsrop(tmpSrc, 0, nend, pdst, 
  476.                 pGC->planemask, rop);
  477.             }
  478.          }
  479.          x += w;
  480.          width -= w;
  481.         }
  482.     }
  483.     ppt++;
  484.     pwidth++;
  485.     }
  486.     DEALLOCATE_LOCAL(pptFree);
  487.     DEALLOCATE_LOCAL(pwidthFree);
  488. }
  489.  
  490.  
  491. /* Fill spans with stipples that aren't 32 bits wide */
  492. void
  493. cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  494. DrawablePtr pDrawable;
  495. GC        *pGC;
  496. int        nInit;        /* number of spans to fill */
  497. DDXPointPtr pptInit;        /* pointer to list of start points */
  498. int *pwidthInit;        /* pointer to list of n widths */
  499. int fSorted;
  500. {
  501.                 /* next three parameters are post-clip */
  502.     int n;            /* number of spans to fill */
  503.     register DDXPointPtr ppt;    /* pointer to list of start points */
  504.     register int *pwidth;    /* pointer to list of n widths */
  505.     int        iline;        /* first line of tile to use */
  506.     int        *addrlBase;    /* pointer to start of bitmap */
  507.     int         nlwidth;    /* width in longwords of bitmap */
  508.     register int *pdst;        /* pointer to current word in bitmap */
  509.     PixmapPtr    pStipple;    /* pointer to stipple we want to fill with */
  510.     register int w;
  511.     int        width,  x, xrem, xSrc, ySrc;
  512.     unsigned int tmpSrc, tmpDst1, tmpDst2;
  513.     int     stwidth, stippleWidth, *psrcS, rop, stiprop;
  514.     int        stippleHeight;
  515.     int *pwidthFree;        /* copies of the pointers to free */
  516.     DDXPointPtr pptFree;
  517.     unsigned int fgfill, bgfill;
  518.  
  519.     if (!(pGC->planemask))
  520.     return;
  521.  
  522.     n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip);
  523.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  524.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  525.     if(!pptFree || !pwidthFree)
  526.     {
  527.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  528.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  529.     return;
  530.     }
  531.     pwidth = pwidthFree;
  532.     ppt = pptFree;
  533.     n = miClipSpans(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip,
  534.              pptInit, pwidthInit, nInit, 
  535.              ppt, pwidth, fSorted);
  536.     rop = pGC->alu;
  537.     if (pGC->fillStyle == FillStippled) {
  538.     switch (rop) {
  539.         case GXand:
  540.         case GXcopy:
  541.         case GXnoop:
  542.         case GXor:
  543.         stiprop = rop;
  544.         break;
  545.         default:
  546.         stiprop = rop;
  547.         rop = GXcopy;
  548.     }
  549.     }
  550.     fgfill = PFILL(pGC->fgPixel);
  551.     bgfill = PFILL(pGC->bgPixel);
  552.  
  553.     /*
  554.      *  OK,  so what's going on here?  We have two Drawables:
  555.      *
  556.      *  The Stipple:
  557.      *        Depth = 1
  558.      *        Width = stippleWidth
  559.      *        Words per scanline = stwidth
  560.      *        Pointer to pixels = pStipple->devPrivate.ptr
  561.      */
  562.     pStipple = pGC->stipple;
  563.  
  564.     if (pStipple->drawable.depth != 1) {
  565.     FatalError( "Stipple depth not equal to 1!\n" );
  566.     }
  567.  
  568.     stwidth = pStipple->devKind >> 2;
  569.     stippleWidth = pStipple->drawable.width;
  570.     stippleHeight = pStipple->drawable.height;
  571.  
  572.     /*
  573.      *    The Target:
  574.      *        Depth = PSZ
  575.      *        Width = determined from *pwidth
  576.      *        Words per scanline = nlwidth
  577.      *        Pointer to pixels = addrlBase
  578.      */
  579.     xSrc = pDrawable->x;
  580.     ySrc = pDrawable->y;
  581.  
  582.     if (pDrawable->type == DRAWABLE_WINDOW)
  583.     {
  584.     addrlBase = (int *)
  585.         (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate.ptr);
  586.     nlwidth = (int)
  587.         (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
  588.     }
  589.     else
  590.     {
  591.     addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate.ptr);
  592.     nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
  593.     }
  594.  
  595.     /* this replaces rotating the stipple. Instead we just adjust the offset
  596.      * at which we start grabbing bits from the stipple.
  597.      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
  598.      * so that iline and xrem always stay within the stipple bounds.
  599.      */
  600.     xSrc += (pGC->patOrg.x % stippleWidth) - stippleWidth;
  601.     ySrc += (pGC->patOrg.y % stippleHeight) - stippleHeight;
  602.  
  603.     while (n--)
  604.     {
  605.     iline = (ppt->y - ySrc) % stippleHeight;
  606.     x = ppt->x;
  607.     pdst = addrlBase + (ppt->y * nlwidth);
  608.         psrcS = (int *) pStipple->devPrivate.ptr + (iline * stwidth);
  609.  
  610.     if (*pwidth)
  611.     {
  612.         width = *pwidth;
  613.         while(width > 0)
  614.         {
  615.             int xtemp, tmpx;
  616.         register unsigned int *ptemp;
  617.         register int *pdsttmp;
  618.         /*
  619.          *  Do a stripe through the stipple & destination w pixels
  620.          *  wide.  w is not more than:
  621.          *    -    the width of the destination
  622.          *    -    the width of the stipple
  623.          *    -    the distance between x and the next word 
  624.          *        boundary in the destination
  625.          *    -    the distance between x and the next word
  626.          *        boundary in the stipple
  627.          */
  628.  
  629.         /* width of dest/stipple */
  630.                 xrem = (x - xSrc) % stippleWidth;
  631.             w = min((stippleWidth - xrem), width);
  632.         /* dist to word bound in dest */
  633.         w = min(w, PPW - (x & PIM));
  634.         /* dist to word bound in stip */
  635.         w = min(w, 32 - (x & 0x1f));
  636.  
  637.             xtemp = (xrem & 0x1f);
  638.             ptemp = (unsigned int *)(psrcS + (xrem >> 5));
  639.         tmpx = x & PIM;
  640.         pdsttmp = pdst + (x>>PWSH);
  641.         switch ( pGC->fillStyle ) {
  642.             case FillOpaqueStippled:
  643.             getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1);
  644.             getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2);
  645.             break;
  646.             case FillStippled:
  647.             /* Fill tmpSrc with the source pixels */
  648.             getbits(pdsttmp, tmpx, w, tmpSrc);
  649.             getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1);
  650.             if (rop != stiprop) {
  651.                 putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop);
  652.             } else {
  653.                 tmpSrc = fgfill;
  654.             }
  655.             getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2);
  656.             break;
  657.         }
  658.         tmpDst2 |= tmpDst1;
  659.         putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop);
  660.         x += w;
  661.         width -= w;
  662.         }
  663.     }
  664. #ifdef    notdef
  665.     if (*pwidth)
  666.     {
  667.         width = *pwidth;
  668.         while(width > 0)
  669.         {
  670.         psrc = psrcS;
  671.             w = min(min(stippleWidth, width), PPW);
  672.         if((rem = x % stippleWidth) != 0)
  673.         {
  674.             w = min(min(stippleWidth - rem, width), PPW);
  675.             /* we want to grab from the end of the tile.  Figure
  676.              * out where that is.  In general, the start of the last
  677.              * word of data on this scanline is stwidth -1 words 
  678.              * away. But if we want to grab more bits than we'll
  679.              * find on that line, we have to back up 1 word further.
  680.              * On the other hand, if the whole tile fits in 1 word,
  681.              * let's skip the work */ 
  682.             endinc = stwidth - 1 - w / PPW;
  683.  
  684.             if(endinc)
  685.             {
  686.             if((rem & 0x1f) + w > stippleWidth % PPW)
  687.                 endinc--;
  688.             }
  689.  
  690.             getbits(psrc + endinc, rem & PIM, w, tmpSrc);
  691.             putbitsrop(tmpSrc, (x & PIM), w, pdst, 
  692.             pGC->planemask, rop);
  693.             if((x & PIM) + w >= PPW)
  694.             pdst++;
  695.         }
  696.  
  697.         else if(((x & PIM) + w) < PPW)
  698.         {
  699.             getbits(psrc, 0, w, tmpSrc);
  700.             putbitsrop(tmpSrc, x & PIM, w, pdst, 
  701.             pGC->planemask, rop);
  702.         }
  703.         else
  704.         {
  705.             maskbits(x, w, startmask, endmask, nlMiddle);
  706.  
  707.                 if (startmask)
  708.                 nstart = PPW - (x & PIM);
  709.                 else
  710.                 nstart = 0;
  711.                 if (endmask)
  712.                     nend = (x + w)  & PIM;
  713.                 else
  714.                 nend = 0;
  715.  
  716.                 srcStartOver = nstart > PLST;
  717.  
  718.             if(startmask)
  719.             {
  720.             getbits(psrc, 0, nstart, tmpSrc);
  721.             putbitsrop(tmpSrc, (x & PIM), nstart, pdst, 
  722.                 pGC->planemask, rop);
  723.             pdst++;
  724.             if(srcStartOver)
  725.                 psrc++;
  726.             }
  727.              
  728.             while(nlMiddle--)
  729.             {
  730.             /*
  731.                 getbits(psrc, nstart, PPW, tmpSrc);
  732.                 putbitsrop( tmpSrc, 0, PPW,
  733.                 pdst, pGC->planemask, rop );
  734.             */
  735.             switch ( pGC->fillStyle ) {
  736.                 case FillStippled:
  737.                 getstipplepixels( psrc, j, 4, 1, pdst, tmp1 );
  738.                 break;
  739.                 case FillOpaqueStippled:
  740.                 getstipplepixels( psrc, j, 4, 1, pdst, tmp1 );
  741.                 break;
  742.             }
  743.             pdst++;
  744.             psrc++;
  745.             }
  746.             if(endmask)
  747.             {
  748.             getbits(psrc, nstart, nend, tmpSrc);
  749.             putbitsrop(tmpSrc, 0, nend, pdst, 
  750.                 pGC->planemask, rop);
  751.             }
  752.          }
  753.          x += w;
  754.          width -= w;
  755.         }
  756.     }
  757. #endif
  758.     ppt++;
  759.     pwidth++;
  760.     }
  761.     DEALLOCATE_LOCAL(pptFree);
  762.     DEALLOCATE_LOCAL(pwidthFree);
  763. }
  764.